<?php namespace Core\Myapp\Router;

class Admin
{
    protected $_modules;
    protected $_module;
    protected $_controller;
    protected $_action;
    protected $_params;
    protected $_adminRoute = 'admin';
    protected $_area = 'admin';

    public function __construct()
    {
        // Collect Module routes
        $this->_modules = array(
            array('route'=>'catalog', 'name'=>'catalog', 'path'=>'core/Catalog'),
            array('route'=>'blog', 'path'=>'core/Blog'),
            array('route'=>'customer', 'path'=>'core/Customer'),
            array('route'=>'checkout', 'path'=>'core/Checkout'),
            array('route'=>'dashboard', 'path'=>'core/Dashboard'),
            array('route'=>'cms', 'path'=>'core/Cms')
        );
        // Set admin route
    }
    public function getArea()
    {
        return $this->_area;
    }
    public function getAdminRoute()
    {
        return $this->_adminRoute;
    }
    public function match(\Core\Zend\Controller\Request\Request $request)
    {
        $path = trim($request->getPathInfo(), '/');
        if (!$path) {
            return false;
        }
        $segments = explode('/', $path);
        if (empty($segments[0]) || $segments[0] != $this->getAdminRoute()) //maybe we need add an option to help user select admin front name
            return false;
        else {
            if (!isset($segments[1])) {
                $this->_module = 'dashboard';
                $this->_controller = 'Modules\Core\Dashboard\Admin\Controller\IndexController';
                $this->_action = 'IndexAction';
                return true;
            } else {
                if (!$this->checkModuleRoute($segments[1]))
                    return false;
                else {
                    if (!isset($segments[2])) {
                        return false;
                    } else {
                        if (!$this->checkController($segments[2]))
                            return false;
                        else {
                            if (!isset($segments[3])) {
                                return false;
                            } else {
                                if (!$this->checkAction($segments[3]))
                                    return false;
                                else {
                                    // set parameters from pathinfo
                                    for ($i = 4, $l = sizeof($segments); $i < $l; $i += 2) {
                                        $request->setParam($segments[$i], !empty($segments[$i+1]) ? urldecode($segments[$i+1]) : '');
                                    }
                                    return true;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    protected function checkModuleRoute($route)
    {
        foreach($this->_modules as $module)
        {
            if($module['route'] == $route) {
                $this->_module = $module;
                return true;
            }
        }
        return false;
    }
    protected function checkController($controller)
    {
        $controller = ucwords($controller) . 'Controller';
        $module = $this->_module;
        $path = $module['path'];
        if(!file_exists(MODULE_PATH . DS . $path . DS . 'Controller' . DS . 'Admin' . DS . $controller . '.php'))
            return false;
        $class = 'Modules\\' . str_replace('/', '\\', ucwords($path)) . '\\Controller\\Admin\\' . $controller;
        if(!class_exists($class))
            return false;
        $this->_controller = $class;
        return true;
    }
    protected function checkAction($action)
    {
        $method = ucwords($action) . 'Action';
        if(!method_exists(new $this->_controller, $method) || !is_callable(array(new $this->_controller, $method)))
            return false;
        $this->_action = $method;
        return true;
    }
    protected function getControllerInstance()
    {
        return new $this->_controller;
    }
    public function run()
    {
        $method = $this->_action;
        $this->getControllerInstance()->$method();
    }
}